- /* sdfcosrn.cpp by K.Tsuru */
- // function ID 3205 DRADIX
- /******************************************************************
- SDouble class
- trigonometric function cos x using x/R^n reduction method
- [Algorithm]
- Pay attention to a formura
- cos(4*x) = 8*cos(x)^4 - 8*cos(x)^2 + 1.
- step 1 : Let R = 4 and d = x/(R^n)(n is an integer).
- step 2 : Evaluate y(n) = cos d by series.
- step 3 : While n > 0, repeat the recurrence formula
- y(n-1) <-- 8*y(n)^4 - 8*y(n)^2 + 1, n <-- n-1.
- It is better to adjust the value of n examining the effective figures.
- When n is too large,it becomes slower.
- Using the conbination with a formula
- cos(2*x)=2*cos(x)^2-1
- and taking R=8,it becomes faster a little.
- *******************************************************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- SDouble CosRN(const SDouble& x){ // |x| <= pi/4
- int k;
- const uint R = 8u;
- const double logR = log10((double)R); // ver. 2.17
- uint effFig = x.EffFig(), upPrec;
- double pw = log10((double)effFig);
- const int n = int(0.5*DFIGURES*pw*pw) + x.RdxExp();
-
- if(n <= 0) return CosSeries(x); // enough small
- // n > 0
- k = int( (double)n*logR )+ 1; //figures of R^n
-
- upPrec = k/DFIGURES + (uint)pw + 1u;
- if(k % DFIGURES) upPrec++;
-
- RealSize C;
- SDouble y, u;
- uint up = x.ProperUpPrec(upPrec);
- //Raises up the precision if possible.
- if(up) C.SetEffFig(effFig + up, C.TEMP_EXTEND);
- u = x/Dpow(R, n); // X = x/(R^n)
- y = CosSeries(u); // CosSeries(u);
- k = n;
- x.iterationCount = k;
- while(k > 0){
- //double angle formula
- y = DsMult(y*y, 2) -ONE;
- //four times angle formula
- //faster than a method using double angle formula three times.
- u = y*y;
- u = u*u-u;
- y = DsMult(u, 8) + ONE;
- k--;
- }
- if(up){
- C.SetEffFig(0);
- y.Reform(3205);
- }
- return y;
- }
sdfcosrn.cpp : last modifiled at 2017/09/07 15:09:42(1,822 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).